In this article, I will be explaining the usage of Azure Worker Role along with Quartz.NET and a practical example showing 3 different jobs running under the same worker role.

What is Azure Worker Role?

"The WorkerRole element describes a role that is useful for generalized development and may perform background processing for a web role. A service may contain zero or more worker roles." Read more here.

What is Quartz.NET?

"Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large-scale enterprise systems." Read more here.

Quartz.NET Key Features
  • Job schedulling
  • Job Persistence
  • Clustering
  • Job Execution
Read more about it's features here.
What are the benefits of using Azure Worker Role + Quartz.Net ?
  • Schedule jobs to run in a certain period of time, saving processing hours. (and money)
  • Schedule more than one job to run in the same instance and much more..
  • Check Azure Pricing here.
  • Check Quartz.Net schedulling options here.
Need help to create your database?
  • Check how to create your local database here.
  • Check how to create your Azure database here.
NuGet Packages required,
  • EntityFramework (database access)
  • Quartz
How to do it?

Create the project as a cloud service project, with the worker role as following.

Azure Worker Role With Quartz.Net
Azure Worker Role With Quartz.Net
You are going to have two projects in your solution, pay attention in the current project when installing the NuGet Packages.
Azure Worker Role With Quartz.Net
These are the jobs that are going to be used here, do not forget that they must inherit from IJob.
  1. public class JobSampleOne : IJob
  2. {
  3. private BusinessSample _business;
  4. public JobSampleOne()
  5. {
  6. _business = new BusinessSample( this.GetType().ToString() );
  7. }
  8. public Task Execute( IJobExecutionContext context )
  9. {
  10. return _business.Ping();
  11. }
  12. }
  1. public class JobSampleTwo : IJob
  2. {
  3. private BusinessSample _business;
  4. public JobSampleTwo()
  5. {
  6. _business = new BusinessSample( this.GetType().ToString() );
  7. }
  8. public async Task Execute( IJobExecutionContext context )
  9. {
  10. await _business.Ping();
  11. }
  12. }
  1. public class JobSampleThree : IJob
  2. {
  3. private BusinessSample _business;
  4. public JobSampleThree()
  5. {
  6. _business = new BusinessSample( this.GetType().ToString() );
  7. }
  8. public async Task Execute( IJobExecutionContext context )
  9. {
  10. await _business.Ping();
  11. }
  12. }
This is the business class definition.
  1. public class BusinessSample
  2. {
  3. private string _jobName;
  4. private SampleContext _sampleContext;
  5. public BusinessSample( string jobName )
  6. {
  7. _jobName = jobName;
  8. _sampleContext = new SampleContext();
  9. }
  10. public Task Ping()
  11. {
  12. _sampleContext.LogSample.Add( new LogSample
  13. {
  14. JobName = _jobName,
  15. LogDate = DateTime.Now
  16. } );
  17. return
  18. _sampleContext.SaveChangesAsync();
  19. }
  20. }
Now, let's schedule these jobs to run in different timing.
  1. public class WorkerRole : RoleEntryPoint
  2. {
  3. private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
  4. private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent( false );
  5. private IScheduler scheduler;
  6. public override void Run()
  7. {
  8. Trace.TraceInformation( "WorkerRoleSample is running" );
  9. try
  10. {
  11. this.RunAsync( this.cancellationTokenSource.Token ).Wait();
  12. }
  13. finally
  14. {
  15. this.runCompleteEvent.Set();
  16. }
  17. }
  18. private void ConfigureScheduler()
  19. {
  20. var scheduleFactory = new StdSchedulerFactory();
  21. scheduler = scheduleFactory.GetScheduler().Result;
  22. IJobDetail job = new JobDetailImpl( "Sample1", typeof( JobSampleOne ) );
  23. IJobDetail jobTwo = new JobDetailImpl( "Sample2", typeof( JobSampleTwo ) );
  24. IJobDetail jobThree = new JobDetailImpl( "Sample3", typeof( JobSampleThree ) );
  25. ITrigger trigger = TriggerBuilder.Create()
  26. .WithSchedule( SimpleScheduleBuilder.RepeatMinutelyForever( 10 ) )
  27. .StartAt( DateTime.Now.AddMinutes( 1 ) )
  28. .Build();
  29. ITrigger triggerTwo = TriggerBuilder.Create()
  30. .WithSchedule( SimpleScheduleBuilder.RepeatMinutelyForever( 6 ) )
  31. .StartAt( DateTime.Now.AddMinutes( 4 ) )
  32. .Build();
  33. ITrigger triggerThree = TriggerBuilder.Create()
  34. .WithSchedule( SimpleScheduleBuilder.RepeatMinutelyForever( 8 ) )
  35. .StartAt( DateTime.Now.AddMinutes( 7 ) )
  36. .Build();
  37. scheduler.ScheduleJob( job, trigger );
  38. scheduler.ScheduleJob( jobTwo, triggerTwo );
  39. scheduler.ScheduleJob( jobThree, triggerThree );
  40. scheduler.Start();
  41. }
  42. public override bool OnStart()
  43. {
  44. // Set the maximum number of concurrent connections
  45. ServicePointManager.DefaultConnectionLimit = 12;
  46. // For information on handling configuration changes
  47. // see the MSDN topic at https://go.microsoft.com/fwlink/?LinkId=166357.
  48. bool result = base.OnStart();
  49. ConfigureScheduler();
  50. Trace.TraceInformation( "WorkerRoleSample has been started" );
  51. return result;
  52. }
  53. public override void OnStop()
  54. {
  55. Trace.TraceInformation( "WorkerRoleSample is stopping" );
  56. this.cancellationTokenSource.Cancel();
  57. this.runCompleteEvent.WaitOne();
  58. base.OnStop();
  59. Trace.TraceInformation( "WorkerRoleSample has stopped" );
  60. }
  61. private async Task RunAsync( CancellationToken cancellationToken )
  62. {
  63. // TODO: Replace the following with your own logic.
  64. while ( !cancellationToken.IsCancellationRequested )
  65. {
  66. Trace.TraceInformation( "Working" );
  67. await Task.Delay( 1000 );
  68. }
  69. }
  70. }
You can see that the first job is going to run after 1 minute of its deployment and then for each 10 minutes. The second job is going to run after 4 minutes of its deployment and then for each 6 minutes. The third job is going to run after 7 minutes of its deployment and after that, for each 8 minutes.
Here, we have the result of the worker role execution for 30 minutes.

Azure Worker Role With Quartz.Net
If you do not know how to publish, you have two options,
  1. Publishing Azure Worker Role Using The Publish Wizard
  2. Publishing Azure Worker Role By Uploading Your Package
Congratulations, you have successfully set up your Azure Worker Role to run along with Quartz.NET.